//! 配置广播功能基础单元测试
//! 
//! 针对配置广播核心功能的基础测试，确保所有核心函数都能正常工作

#[cfg(feature = "broadcast")]
use crate::broadcast::*;
#[cfg(feature = "broadcast")]  
use crate::bus_broadcast::*;
use crate::error::{ConfigResult, ConfigError};

use std::collections::HashMap;
use std::sync::Arc;
use std::time::SystemTime;
use serde_json::{json, Value};

// ============================================================================
// ConfigBroadcastEventType 基础测试
// ============================================================================

#[cfg(test)]
#[cfg(feature = "broadcast")]
mod config_broadcast_event_type_basic_tests {
    use super::*;

    #[test]
    fn test_config_broadcast_event_type_as_str() {
        // 测试所有事件类型的字符串表示
        assert_eq!(ConfigBroadcastEventType::ConfigUpdate.as_str(), "config.update");
        assert_eq!(ConfigBroadcastEventType::ConfigDelete.as_str(), "config.delete");
        assert_eq!(ConfigBroadcastEventType::ConfigRefresh.as_str(), "config.refresh");
        assert_eq!(ConfigBroadcastEventType::ServiceRestart.as_str(), "service.restart");
    }

    #[test]
    fn test_config_broadcast_event_type_equality() {
        // 测试事件类型相等性
        assert_eq!(ConfigBroadcastEventType::ConfigUpdate, ConfigBroadcastEventType::ConfigUpdate);
        assert_ne!(ConfigBroadcastEventType::ConfigUpdate, ConfigBroadcastEventType::ConfigDelete);
        assert_ne!(ConfigBroadcastEventType::ConfigRefresh, ConfigBroadcastEventType::ServiceRestart);
    }

    #[test]
    fn test_config_broadcast_event_type_clone() {
        // 测试克隆功能
        let event_type = ConfigBroadcastEventType::ConfigUpdate;
        let cloned = event_type.clone();
        assert_eq!(event_type, cloned);
        
        let event_type2 = ConfigBroadcastEventType::ServiceRestart;
        let cloned2 = event_type2.clone();
        assert_eq!(event_type2, cloned2);
    }

    #[test]
    fn test_config_broadcast_event_type_debug() {
        // 测试Debug输出
        let event_type = ConfigBroadcastEventType::ConfigUpdate;
        let debug_str = format!("{:?}", event_type);
        assert!(debug_str.contains("ConfigUpdate"));
        
        let event_type2 = ConfigBroadcastEventType::ConfigDelete;
        let debug_str2 = format!("{:?}", event_type2);
        assert!(debug_str2.contains("ConfigDelete"));
    }

    #[test]
    fn test_config_broadcast_event_type_serialization() {
        // 测试序列化
        let event_type = ConfigBroadcastEventType::ConfigUpdate;
        let serialized = serde_json::to_string(&event_type).unwrap();
        assert!(serialized.contains("ConfigUpdate"));
        
        // 测试反序列化
        let deserialized: ConfigBroadcastEventType = serde_json::from_str(&serialized).unwrap();
        assert_eq!(event_type, deserialized);
        
        // 测试所有类型
        let all_types = vec![
            ConfigBroadcastEventType::ConfigUpdate,
            ConfigBroadcastEventType::ConfigDelete,
            ConfigBroadcastEventType::ConfigRefresh,
            ConfigBroadcastEventType::ServiceRestart,
        ];
        
        for event_type in all_types {
            let serialized = serde_json::to_string(&event_type).unwrap();
            let deserialized: ConfigBroadcastEventType = serde_json::from_str(&serialized).unwrap();
            assert_eq!(event_type, deserialized);
        }
    }
}

// ============================================================================
// ConfigBroadcastEvent 基础测试
// ============================================================================

#[cfg(test)]
#[cfg(feature = "broadcast")]
mod config_broadcast_event_basic_tests {
    use super::*;

    #[test]
    fn test_config_broadcast_event_config_update_creation() {
        // 测试配置更新事件创建 - 完整参数
        let event = ConfigBroadcastEvent::config_update(
            "user-service",
            "production",
            Some("v1.0"),
            "database.url",
            Some(json!("old-url")),
            json!("new-url"),
            "config-server",
            Some("admin"),
        );

        assert_eq!(event.application, "user-service");
        assert_eq!(event.profile, "production");
        assert_eq!(event.label, Some("v1.0".to_string()));
        assert_eq!(event.config_path, Some("database.url".to_string()));
        assert_eq!(event.old_value, Some(json!("old-url")));
        assert_eq!(event.new_value, Some(json!("new-url")));
        assert_eq!(event.source_service, "config-server");
        assert_eq!(event.user, Some("admin".to_string()));
        assert_eq!(event.event_type, ConfigBroadcastEventType::ConfigUpdate);
        assert!(event.id.starts_with("config_update_"));
        assert!(event.target_services.is_none());
        
        // 检查时间戳是最近的
        let now = SystemTime::now();
        let duration = now.duration_since(event.timestamp).unwrap_or_default();
        assert!(duration.as_secs() < 5); // 应该在5秒内创建
    }

    #[test]
    fn test_config_broadcast_event_config_update_minimal_params() {
        // 测试配置更新事件创建 - 最小参数
        let event = ConfigBroadcastEvent::config_update(
            "service",
            "dev",
            None,
            "key",
            None,
            json!("value"),
            "source",
            None,
        );

        assert_eq!(event.application, "service");
        assert_eq!(event.profile, "dev");
        assert_eq!(event.label, None);
        assert_eq!(event.user, None);
        assert_eq!(event.old_value, None);
        assert_eq!(event.new_value, Some(json!("value")));
        assert_eq!(event.config_path, Some("key".to_string()));
        assert_eq!(event.source_service, "source");
    }

    #[test]
    fn test_config_broadcast_event_service_restart_creation() {
        // 测试服务重启事件创建 - 有目标服务
        let target_services = vec!["service1".to_string(), "service2".to_string()];
        let event = ConfigBroadcastEvent::service_restart(
            "app",
            "source-service",
            Some(target_services.clone()),
            Some("operator"),
        );

        assert_eq!(event.application, "app");
        assert_eq!(event.profile, "");
        assert_eq!(event.source_service, "source-service");
        assert_eq!(event.target_services, Some(target_services));
        assert_eq!(event.user, Some("operator".to_string()));
        assert_eq!(event.event_type, ConfigBroadcastEventType::ServiceRestart);
        assert!(event.id.starts_with("service_restart_"));
        assert_eq!(event.config_path, None);
        assert_eq!(event.old_value, None);
        assert_eq!(event.new_value, None);
    }

    #[test]
    fn test_config_broadcast_event_config_refresh_creation() {
        // 测试配置刷新事件创建
        let targets = vec!["target1".to_string()];
        let event = ConfigBroadcastEvent::config_refresh(
            "application",
            "staging",
            "config-server",
            Some(targets.clone()),
        );

        assert_eq!(event.application, "application");
        assert_eq!(event.profile, "staging");
        assert_eq!(event.source_service, "config-server");
        assert_eq!(event.target_services, Some(targets));
        assert_eq!(event.event_type, ConfigBroadcastEventType::ConfigRefresh);
        assert!(event.id.starts_with("config_refresh_"));
        assert_eq!(event.user, None);
        assert_eq!(event.config_path, None);
        assert_eq!(event.old_value, None);
        assert_eq!(event.new_value, None);
    }

    #[test]
    fn test_config_broadcast_event_empty_strings() {
        // 测试空字符串参数
        let event = ConfigBroadcastEvent::config_update(
            "",
            "",
            Some(""),
            "",
            None,
            json!(""),
            "",
            Some(""),
        );

        assert_eq!(event.application, "");
        assert_eq!(event.profile, "");
        assert_eq!(event.label, Some("".to_string()));
        assert_eq!(event.config_path, Some("".to_string()));
        assert_eq!(event.source_service, "");
        assert_eq!(event.user, Some("".to_string()));
    }

    #[test]
    fn test_config_broadcast_event_unicode_strings() {
        // 测试Unicode字符串
        let event = ConfigBroadcastEvent::config_update(
            "用户服务",
            "生产环境",
            Some("版本1.0"),
            "数据库.地址",
            Some(json!("旧地址")),
            json!("新地址"),
            "配置服务器",
            Some("管理员"),
        );

        assert_eq!(event.application, "用户服务");
        assert_eq!(event.profile, "生产环境");
        assert_eq!(event.label, Some("版本1.0".to_string()));
        assert_eq!(event.config_path, Some("数据库.地址".to_string()));
        assert_eq!(event.source_service, "配置服务器");
        assert_eq!(event.user, Some("管理员".to_string()));
    }

    #[test]
    fn test_config_broadcast_event_large_data() {
        // 测试大数据量
        let large_config = json!({
            "database": {
                "connections": (0..100).map(|i| format!("connection_{}", i)).collect::<Vec<_>>(),
                "settings": {
                    "timeout": 30000,
                    "pool_size": 50
                }
            },
            "features": (0..50).map(|i| format!("feature_{}", i)).collect::<Vec<_>>()
        });

        let event = ConfigBroadcastEvent::config_update(
            "large-service",
            "prod",
            None,
            "complex.config",
            None,
            large_config.clone(),
            "config-server",
            None,
        );

        assert_eq!(event.new_value, Some(large_config));
        assert_eq!(event.application, "large-service");
    }

    #[test]
    fn test_config_broadcast_event_serialization() {
        // 测试事件序列化和反序列化
        let event = ConfigBroadcastEvent::config_update(
            "test-service",
            "test",
            None,
            "test.key",
            None,
            json!({"nested": {"key": "value"}}),
            "source",
            None,
        );

        let serialized = serde_json::to_string(&event).unwrap();
        let deserialized: ConfigBroadcastEvent = serde_json::from_str(&serialized).unwrap();

        assert_eq!(event.application, deserialized.application);
        assert_eq!(event.profile, deserialized.profile);
        assert_eq!(event.event_type, deserialized.event_type);
        assert_eq!(event.source_service, deserialized.source_service);
        assert_eq!(event.new_value, deserialized.new_value);
    }

    #[test]
    fn test_config_broadcast_event_clone() {
        // 测试事件克隆
        let event = ConfigBroadcastEvent::config_update(
            "service",
            "profile",
            None,
            "key",
            None,
            json!("value"),
            "source",
            None,
        );

        let cloned = event.clone();
        assert_eq!(event.id, cloned.id);
        assert_eq!(event.application, cloned.application);
        assert_eq!(event.event_type, cloned.event_type);
        assert_eq!(event.new_value, cloned.new_value);
    }
}

// ============================================================================
// ServiceState 和 BroadcastStats 基础测试
// ============================================================================

#[cfg(test)]
#[cfg(feature = "broadcast")]
mod service_state_basic_tests {
    use super::*;

    #[test]
    fn test_service_state_creation() {
        let mut metadata = HashMap::new();
        metadata.insert("version".to_string(), "1.0.0".to_string());
        metadata.insert("region".to_string(), "us-west-1".to_string());
        
        let state = ServiceState {
            service_name: "test-service".to_string(),
            last_heartbeat: SystemTime::now(),
            config_version: "v1.0".to_string(),
            status: ServiceStatus::Running,
            metadata: metadata.clone(),
        };

        assert_eq!(state.service_name, "test-service");
        assert_eq!(state.config_version, "v1.0");
        assert_eq!(state.status, ServiceStatus::Running);
        assert_eq!(state.metadata, metadata);
        assert_eq!(state.metadata.len(), 2);
    }

    #[test]
    fn test_service_status_equality() {
        assert_eq!(ServiceStatus::Running, ServiceStatus::Running);
        assert_ne!(ServiceStatus::Running, ServiceStatus::Stopped);
        assert_ne!(ServiceStatus::Restarting, ServiceStatus::Syncing);
    }

    #[test]
    fn test_service_status_serialization() {
        let all_statuses = vec![
            ServiceStatus::Running,
            ServiceStatus::Restarting,
            ServiceStatus::Stopped,
            ServiceStatus::Syncing,
        ];
        
        for status in all_statuses {
            let serialized = serde_json::to_string(&status).unwrap();
            let deserialized: ServiceStatus = serde_json::from_str(&serialized).unwrap();
            assert_eq!(status, deserialized);
        }
    }

    #[test]
    fn test_broadcast_stats_default() {
        let stats = BroadcastStats::default();
        
        assert_eq!(stats.events_sent, 0);
        assert_eq!(stats.events_received, 0);
        assert_eq!(stats.events_processed, 0);
        assert_eq!(stats.events_failed, 0);
        assert_eq!(stats.active_listeners, 0);
        assert!(stats.last_processed.is_none());
    }

    #[test]
    fn test_broadcast_stats_clone() {
        let mut stats = BroadcastStats::default();
        stats.events_sent = 10;
        stats.events_received = 15;
        stats.events_processed = 12;
        stats.events_failed = 3;
        stats.active_listeners = 5;
        stats.last_processed = Some(SystemTime::now());
        
        let cloned = stats.clone();
        assert_eq!(stats.events_sent, cloned.events_sent);
        assert_eq!(stats.events_received, cloned.events_received);
        assert_eq!(stats.events_processed, cloned.events_processed);
        assert_eq!(stats.events_failed, cloned.events_failed);
        assert_eq!(stats.active_listeners, cloned.active_listeners);
        assert_eq!(stats.last_processed, cloned.last_processed);
    }

    #[test]
    fn test_broadcast_stats_serialization() {
        let mut stats = BroadcastStats::default();
        stats.events_sent = 100;
        stats.events_received = 200;
        
        let serialized = serde_json::to_string(&stats).unwrap();
        let deserialized: BroadcastStats = serde_json::from_str(&serialized).unwrap();
        
        assert_eq!(stats.events_sent, deserialized.events_sent);
        assert_eq!(stats.events_received, deserialized.events_received);
    }
}

// ============================================================================
// ConfigMessage 基础测试
// ============================================================================

#[cfg(test)]
#[cfg(feature = "broadcast")]
mod config_message_basic_tests {
    use super::*;

    #[test]
    fn test_config_message_creation() {
        let payload = json!({"test": "data", "number": 42});
        let message = ConfigMessage::new(
            "test.topic".to_string(),
            payload.clone(),
        );

        assert_eq!(message.topic, "test.topic");
        assert_eq!(message.payload, payload);
        assert!(message.id.starts_with("msg_"));
        assert!(message.headers.is_empty());
        assert!(message.correlation_id.is_none());
        
        // 检查时间戳是最近的
        let now = SystemTime::now();
        let duration = now.duration_since(message.timestamp).unwrap_or_default();
        assert!(duration.as_secs() < 1);
    }

    #[test]
    fn test_config_message_with_header() {
        let message = ConfigMessage::new(
            "topic".to_string(),
            json!({}),
        ).with_header("key1".to_string(), "value1".to_string())
         .with_header("key2".to_string(), "value2".to_string())
         .with_header("Content-Type".to_string(), "application/json".to_string());

        assert_eq!(message.headers.len(), 3);
        assert_eq!(message.headers.get("key1"), Some(&"value1".to_string()));
        assert_eq!(message.headers.get("key2"), Some(&"value2".to_string()));
        assert_eq!(message.headers.get("Content-Type"), Some(&"application/json".to_string()));
    }

    #[test]
    fn test_config_message_with_correlation_id() {
        let correlation_id = "test-correlation-123";
        let message = ConfigMessage::new(
            "topic".to_string(),
            json!({}),
        ).with_correlation_id(correlation_id.to_string());

        assert_eq!(message.correlation_id, Some(correlation_id.to_string()));
    }

    #[test]
    fn test_config_message_chaining() {
        // 测试方法链式调用
        let message = ConfigMessage::new(
            "test.topic".to_string(),
            json!({"data": "test"}),
        )
        .with_header("type".to_string(), "config".to_string())
        .with_header("source".to_string(), "server".to_string())
        .with_header("priority".to_string(), "high".to_string())
        .with_correlation_id("corr-123".to_string());

        assert_eq!(message.topic, "test.topic");
        assert_eq!(message.headers.len(), 3);
        assert_eq!(message.correlation_id, Some("corr-123".to_string()));
        assert_eq!(message.headers.get("type"), Some(&"config".to_string()));
        assert_eq!(message.headers.get("source"), Some(&"server".to_string()));
        assert_eq!(message.headers.get("priority"), Some(&"high".to_string()));
    }

    #[test]
    fn test_config_message_empty_topic() {
        let message = ConfigMessage::new(
            "".to_string(),
            json!(null),
        );

        assert_eq!(message.topic, "");
        assert_eq!(message.payload, json!(null));
    }

    #[test]
    fn test_config_message_complex_payload() {
        let complex_payload = json!({
            "config": {
                "database": {
                    "host": "localhost",
                    "port": 5432,
                    "credentials": {
                        "username": "admin",
                        "password": "secret"
                    }
                },
                "features": ["auth", "cache", "monitoring"],
                "settings": {
                    "timeout": 30,
                    "retries": 3
                }
            },
            "metadata": {
                "version": "1.0.0",
                "environment": "production",
                "timestamp": "2024-01-01T00:00:00Z"
            }
        });

        let message = ConfigMessage::new(
            "config.complex".to_string(),
            complex_payload.clone(),
        );

        assert_eq!(message.payload, complex_payload);
        assert_eq!(message.topic, "config.complex");
    }

    #[test]
    fn test_config_message_clone() {
        let original = ConfigMessage::new(
            "topic".to_string(),
            json!({"test": "data"}),
        )
        .with_header("key".to_string(), "value".to_string())
        .with_correlation_id("corr-id".to_string());

        let cloned = original.clone();
        
        assert_eq!(original.id, cloned.id);
        assert_eq!(original.topic, cloned.topic);
        assert_eq!(original.payload, cloned.payload);
        assert_eq!(original.headers, cloned.headers);
        assert_eq!(original.correlation_id, cloned.correlation_id);
    }
}

// ============================================================================
// InMemoryConfigMessageBus 基础测试
// ============================================================================

#[cfg(test)]
#[cfg(feature = "broadcast")]
mod in_memory_message_bus_basic_tests {
    use super::*;

    #[tokio::test]
    async fn test_in_memory_message_bus_creation() {
        let bus = InMemoryConfigMessageBus::new();
        
        // 测试创建发布者
        let publisher_result = bus.create_publisher().await;
        assert!(publisher_result.is_ok());
        
        // 测试创建订阅者
        let subscriber_result = bus.create_subscriber().await;
        assert!(subscriber_result.is_ok());
    }

    #[tokio::test]
    async fn test_in_memory_message_bus_publish_subscribe() {
        let bus = Arc::new(InMemoryConfigMessageBus::new());
        
        // 创建发布者和订阅者
        let publisher = bus.create_publisher().await.unwrap();
        let subscriber = bus.create_subscriber().await.unwrap();
        
        // 订阅主题
        subscriber.subscribe("test.topic").await.unwrap();
        
        // 发布消息
        let message = ConfigMessage::new(
            "test.topic.specific".to_string(),
            json!({"data": "test", "id": 123}),
        );
        publisher.publish(message.clone()).await.unwrap();
        
        // 接收消息
        let received = subscriber.receive().await.unwrap();
        assert!(received.is_some());
        
        let received_msg = received.unwrap();
        assert_eq!(received_msg.topic, message.topic);
        assert_eq!(received_msg.payload, message.payload);
    }

    #[tokio::test]
    async fn test_in_memory_message_bus_multiple_messages() {
        let bus = Arc::new(InMemoryConfigMessageBus::new());
        let publisher = bus.create_publisher().await.unwrap();
        let subscriber = bus.create_subscriber().await.unwrap();
        
        subscriber.subscribe("test").await.unwrap();
        
        // 发布多条消息
        for i in 0..5 {
            let message = ConfigMessage::new(
                format!("test.message.{}", i),
                json!({"index": i, "data": format!("message_{}", i)}),
            );
            publisher.publish(message).await.unwrap();
        }
        
        // 接收所有消息
        let mut received_count = 0;
        while let Ok(Some(_)) = subscriber.receive().await {
            received_count += 1;
        }
        
        assert_eq!(received_count, 5);
    }

    #[tokio::test]
    async fn test_in_memory_message_bus_topic_filtering() {
        let bus = Arc::new(InMemoryConfigMessageBus::new());
        let publisher = bus.create_publisher().await.unwrap();
        let subscriber = bus.create_subscriber().await.unwrap();
        
        // 只订阅特定主题
        subscriber.subscribe("config.update").await.unwrap();
        
        // 发布不同主题的消息
        let config_message = ConfigMessage::new(
            "config.update.database".to_string(),
            json!({"type": "config", "key": "database.url"}),
        );
        let other_message = ConfigMessage::new(
            "system.notification".to_string(),
            json!({"type": "notification", "message": "system update"}),
        );
        
        publisher.publish(config_message).await.unwrap();
        publisher.publish(other_message).await.unwrap();
        
        // 应该只收到匹配的消息
        let received = subscriber.receive().await.unwrap();
        assert!(received.is_some());
        assert!(received.unwrap().topic.starts_with("config.update"));
        
        // 第二次调用应该没有更多消息（other_message被过滤掉了）
        let no_more = subscriber.receive().await.unwrap();
        assert!(no_more.is_none());
    }

    #[tokio::test]
    async fn test_in_memory_message_bus_unsubscribe() {
        let bus = Arc::new(InMemoryConfigMessageBus::new());
        let publisher = bus.create_publisher().await.unwrap();
        let subscriber = bus.create_subscriber().await.unwrap();
        
        subscriber.subscribe("test.topic").await.unwrap();
        
        // 发布消息前取消订阅
        subscriber.unsubscribe("test.topic").await.unwrap();
        
        let message = ConfigMessage::new(
            "test.topic.message".to_string(),
            json!({"data": "test"}),
        );
        publisher.publish(message).await.unwrap();
        
        // 应该收不到消息
        let received = subscriber.receive().await.unwrap();
        assert!(received.is_none());
    }
}